//
//  NSString+YCExtension.m
//  YCPublicDemo
//
//  Created by xinhuanwangluo on 2017/5/17.
//  Copyright © 2017年 xinhuanwangluo. All rights reserved.
//

#import "NSString+YCExtension.h"
#import <CommonCrypto/CommonDigest.h>
#import <sys/sysctl.h>
#import <sys/socket.h>
#import <net/if.h>
#import <net/if_dl.h>

#import <ifaddrs.h>
#import <arpa/inet.h>
#import <sys/utsname.h>
#import <net/if.h>

#import "NSDateFormatter+YCExtension.h"



#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
#define IOS_VPN         @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"



@implementation NSString (YCExtension)

+ (NSString *)yc_currentYMDHMSString {
    
    return [NSDateFormatter yc_ymdWithDate:[NSDate date]];

}


- (CGFloat)yc_heightWithWidth:(CGFloat)width font:(CGFloat)font {
    
    // 计算文本的大小
    CGSize sizeToFit = [self boundingRectWithSize:CGSizeMake(width, MAXFLOAT) // 用于计算文本绘制时占据的矩形块
                                          options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading // 文本绘制时的附加选项
                                       attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}        // 文字的属性
                                          context:nil].size; // context上下文。包括一些信息，例如如何调整字间距以及缩放。该对象包含的信息将用于文本绘制。该参数可为nil
    return ceilf(sizeToFit.height);

}

- (CGFloat)yc_widthWithHeight:(CGFloat)height font:(CGFloat)font {

    // 计算文本的大小
    CGSize sizeToFit = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, height) // 用于计算文本绘制时占据的矩形块
                                          options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading // 文本绘制时的附加选项
                                       attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}        // 文字的属性
                                          context:nil].size; // context上下文。包括一些信息，例如如何调整字间距以及缩放。该对象包含的信息将用于文本绘制。该参数可为nil
    return ceilf(sizeToFit.width);


}

- (CGFloat)yc_heightFromStringWithFont:(CGFloat)font lineSpace:(CGFloat)lineSpace width:(CGFloat)width label:(UILabel *)label{

    UILabel * tempLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, width, 0)];
    tempLabel.numberOfLines = 0;
    
    NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc]initWithString:self];
    NSMutableParagraphStyle * paragrapStyle = [[NSMutableParagraphStyle alloc]init];
    [paragrapStyle setLineSpacing:lineSpace];
    [attrString addAttribute:NSParagraphStyleAttributeName value:paragrapStyle range:NSMakeRange(0, self.length)];
    [attrString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:font] range:NSMakeRange(0, self.length)];
    
    tempLabel.attributedText = attrString;
    [tempLabel sizeToFit];
    label.numberOfLines = 0;
    label.attributedText = attrString;
    return tempLabel.frame.size.height;


}

+ (NSString *)yc_getSecretStringWithPhoneNumer:(NSString *)phoneNum {
    
    BOOL isValidPhoneNumber = [NSString yc_isValidPhone:phoneNum];
    
    if (isValidPhoneNumber) {
        
        NSMutableString * newStr = [NSMutableString stringWithString:phoneNum];
        NSRange range = NSMakeRange(3, 4);
        [newStr replaceCharactersInRange:range withString:@"****"];
        return newStr;
        
    } else {
    
        NSLog(@"手机号码格式不正确");
        
        
    }
    return nil;

}

+ (NSString *)yc_getSecretStringWithBankCard:(NSString *)bankCard {

    NSMutableString * newStr = [NSMutableString stringWithString:bankCard];
    NSRange range = NSMakeRange(4, 8);
    if (newStr.length > 12) {
        
        [newStr replaceCharactersInRange:range withString:@"**** ****"];
    }
    return newStr;
}


@end

@implementation NSAttributedString (YCExtension)

+ (NSAttributedString *)yc_attributeStringWithPrefixString:(NSString *)prefixString suffixString:(NSString *)suffixString {
    
    return [self yc_attributeStringWithPrefixString:prefixString
                                      prefixFont:0
                                     prefixColor:0
                                    suffixString:suffixString
                                      suffixFont:0
                                     suffixColor:0];
}

+ (NSAttributedString *)yc_attributeStringWithPrefixString:(NSString *)prefixString
                                             prefixFont:(CGFloat)prefixFont
                                            prefixColor:(UInt32)prefixColor
                                           suffixString:(NSString *)suffixString
                                             suffixFont:(CGFloat)suffixFont
                                            suffixColor:(UInt32)suffixColor{
    NSInteger prefixLength = prefixString.length;
    NSInteger suffixLength = suffixString.length;
    
    NSString *finalString = [NSString stringWithFormat:@"%@%@", prefixString, suffixString];
    
    
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:finalString];
    
    if (prefixFont==0 && prefixColor==0) {
        [attributedString addAttributes:@{NSForegroundColorAttributeName: [UIColor colorWithRGBValue:0x999999],
                                          NSFontAttributeName: [UIFont systemFontOfSize:10.0f]
                                          }
                                  range:NSMakeRange(0, prefixLength)];
        
        
    }else {
        [attributedString addAttributes:@{NSForegroundColorAttributeName: [UIColor colorWithRGBValue:prefixColor],
                                          NSFontAttributeName: [UIFont systemFontOfSize:prefixFont]
                                          }
                                  range:NSMakeRange(0, prefixLength)];
    }
    
    if (suffixFont==0 && suffixColor==0) {
        [attributedString addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:10.0f],
                                          NSForegroundColorAttributeName: [UIColor colorWithRGBValue:0xff786e]}
                                  range:NSMakeRange(prefixLength, suffixLength)];
    }else {
        
        
        [attributedString addAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:suffixFont],
                                          NSForegroundColorAttributeName: [UIColor colorWithRGBValue:suffixColor]}
                                  range:NSMakeRange(prefixLength, suffixLength)];
    }
    
    
    return attributedString;
}


@end


static char base64EncodingTable[64] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};

@implementation NSString(ycString)


- (NSString *)yc_md5 {
    if (self == nil || [self length] == 0) {
        return nil;
    }
    
    unsigned char digest[CC_MD5_DIGEST_LENGTH], i;
    CC_MD5([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
    NSMutableString *ms = [NSMutableString string];
    
    for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [ms appendFormat:@"%02x", (int)(digest[i])];
    }
    
    return [ms copy];
}

- (NSString *)yc_SHA1 {
    if (self == nil || [self length] == 0) {
        return nil;
    }
    
    unsigned char digest[CC_SHA1_DIGEST_LENGTH], i;
    CC_SHA1([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
    NSMutableString *ms = [NSMutableString string];
    
    for ( i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
        [ms appendFormat:@"%02x", (int)(digest[i])];
    }
    
    return [ms copy];
}

- (NSString *)yc_SHA256 {
    if (self == nil || [self length] == 0) {
        return nil;
    }
    
    unsigned char digest[CC_SHA256_DIGEST_LENGTH], i;
    CC_SHA256([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
    NSMutableString *ms = [NSMutableString string];
    
    for (i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [ms appendFormat: @"%02x", (int)(digest[i])];
    }
    
    return [ms copy];
}

- (NSString *)yc_SHA512 {
    if (self == nil || [self length] == 0) {
        return nil;
    }
    
    unsigned char digest[CC_SHA512_DIGEST_LENGTH], i;
    CC_SHA512([self UTF8String], (int)[self lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
    NSMutableString *ms = [NSMutableString string];
    
    for (i = 0; i < CC_SHA512_DIGEST_LENGTH; i++) {
        [ms appendFormat: @"%02x", (int)(digest[i])];
    }
    
    return [ms copy];
}

- (NSData *)yc_toData {
    return [self dataUsingEncoding:NSUTF8StringEncoding];
}

+ (NSString *)yc_toString:(NSData *)data {
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

- (NSString *)yc_base64Encoding {
    return [NSString yc_base64Encoding:self];
}

+ (NSString *)yc_base64Encoding:(NSString *)text {
    NSData *data = [text yc_toData];
    NSString *result = nil;
    
    // 7.0以下版本不可用
    result = [data base64EncodedStringWithOptions:0];
    
    return result;
}

+ (NSString *)yc_textWithBase64Encoding:(NSString *)base64Encoding {
    if (base64Encoding != nil) {
        NSData *data = [self _dataWithBase64EncodedString:base64Encoding];
        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    
    return nil;
}

- (BOOL)yc_isValidEmail {
    return [NSString yc_isValidEmail:self];
}

+ (BOOL)yc_isValidEmail:(NSString *)email {
    NSString *emailRegEx =
    @"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
    @"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
    @"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
    @"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
    @"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
    @"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
    @"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
    
    NSPredicate *regExPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegEx];
    return [regExPredicate evaluateWithObject:[email lowercaseString]];
}

- (NSString *)yc_trimLeft {
    NSUInteger len = 0;
    
    while (len < self.length) {
        if ([self characterAtIndex:len] != ' ') {
            break;
        }
        
        len++;
    }
    
    if (len >= self.length) {
        len = self.length;
    }
    
    return [self substringFromIndex:len];
}

- (NSString *)yc_trimRight {
    NSInteger index = self.length - 1;
    for (NSInteger i = self.length - 1; i >= 0; --i) {
        if ([self characterAtIndex:i] != ' ') {
            break;
        } else {
            index--;
        }
    }
    
    if (index + 1 < self.length) {
        index++;
    }
    
    return [self substringToIndex:index];
}

- (NSString *)yc_trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

- (NSString *)yc_trimAll {
    NSString *tempString = self.yc_trim;
    return [tempString stringByReplacingOccurrencesOfString:@" " withString:@""];
}

- (NSString *)yc_trimLetters {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]];
}

- (NSString *)yc_trimCharacter:(unichar)character {
    NSString *str = [NSString stringWithFormat:@"%c", character];
    return [self stringByReplacingOccurrencesOfString:str withString:@""];
}

- (NSString *)yc_trimWhitespace {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSUInteger)yc_numberOfLines {
    return [self componentsSeparatedByString:@"\n"].count + 1;
}

- (BOOL)yc_isOnlyLetters {
    NSCharacterSet *letterCharacterset = [[NSCharacterSet letterCharacterSet] invertedSet];
    return ([self rangeOfCharacterFromSet:letterCharacterset].location == NSNotFound);
}

- (BOOL)yc_isOnlyNumbers {
    NSCharacterSet *numSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
    return ([self rangeOfCharacterFromSet:numSet].location == NSNotFound);
}

- (BOOL)yc_isOnlyAlphaNumeric {
    NSCharacterSet *numAndLetterCharSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
    return ([self rangeOfCharacterFromSet:numAndLetterCharSet].location == NSNotFound);
}

+ (BOOL)yc_isNumOrLetter:(NSString *)string
{
    NSString *		regex = @"(^[A-Za-z0-9]{0,}$)";
    NSPredicate *	pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    
    return [pred evaluateWithObject:string];
}

- (BOOL)yc_isEmpty {
    return self == nil || self.length == 0;
}

- (BOOL)yc_isTrimEmpty {
    return self == nil || self.yc_trim.length == 0;
}

- (BOOL)yc_isValidPhone {
    return [NSString yc_isValidPhone:self];
}

+ (BOOL)yc_isValidPhone:(NSString *)phone {
//    NSString *pattern = @"^1\\d{10}$";
//    
//    NSPredicate *mobilePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
//    if ([mobilePredicate evaluateWithObject:phone]) {
//        return YES;
//    }
//    
//    return NO;
    
    if (phone.length <11) return NO;
    NSString *phoneRegex = @"^1[34578]\\d{9}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    
    
    return [phoneTest evaluateWithObject:phone];

}

//+ (BOOL)yc_isValidPhone:(NSString *)phone {
//  /**
//   * 手机号码
//   * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
//   * 联通：130,131,132,152,155,156,185,186
//   * 电信：133,1349,153,180,189
//   */
//  NSString *mobile = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
//  /**
//   10         * 中国移动：China Mobile
//   11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
//   12         */
//  NSString *chinaMobile = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
//  /**
//   15         * 中国联通：China Unicom
//   16         * 130,131,132,152,155,156,185,186
//   17         */
//  NSString * chinaUnicom = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
//  /**
//   20         * 中国电信：China Telecom
//   21         * 133,1349,153,180,189
//   22         */
//  NSString * chinaTelecom = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
//
//  NSPredicate *mobilePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", mobile];
//  NSPredicate *cmPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", chinaMobile];
//  NSPredicate *cuPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", chinaUnicom];
//  NSPredicate *ctPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", chinaTelecom];
//  if ([mobilePredicate evaluateWithObject:phone]
//      || [cmPredicate evaluateWithObject:phone]
//      || [cuPredicate evaluateWithObject:phone]
//      || [ctPredicate evaluateWithObject:phone]) {
//    return YES;
//  }
//
//  return NO;
//}

- (BOOL)yc_isValidTelNumber {
    return [NSString yc_isValidTelNumber:self];
}

+ (BOOL)yc_isValidTelNumber:(NSString *)telNumber {
    NSString *PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", PHS];
    
    return [pred evaluateWithObject:telNumber];
}

- (BOOL)yc_isValidPersonID {
    return [NSString yc_isValidPersonID:self];
}

+ (BOOL)yc_isValidPersonID:(NSString *)PID {
    // 判断位数 取消15位数的判断
    if (PID.length != 18) {
        return NO;
    }
    NSString *carid = PID;
    long lSumQT = 0;
    // 加权因子
    int R[] ={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
    // 校验码
    unsigned char sChecker[11]={'1','0','X', '9', '8', '7', '6', '5', '4', '3', '2'};
    
    // 将15位身份证号转换成18位
    NSMutableString *mString = [NSMutableString stringWithString:PID];
    if (PID.length == 15) {
        [mString insertString:@"19" atIndex:6];
        long p = 0;
        const char *pid = [mString UTF8String];
        
        for (int i = 0; i<= 16; i++) {
            p += (pid[i] - 48) * R[i];
        }
        
        int o = p % 11;
        NSString *string_content = [NSString stringWithFormat:@"%c", sChecker[o]];
        [mString insertString:string_content atIndex:[mString length]];
        carid = mString;
    }
    
    // 判断地区码
    NSString * sProvince = [carid substringToIndex:2];
    if (![self _areaCode:sProvince]) {
        return NO;
    }
    
    // 判断年月日是否有效
    // 年份
    int strYear = [[self _substringWithString:carid begin:6 end:4] intValue];
    // 月份
    int strMonth = [[self _substringWithString:carid begin:10 end:2] intValue];
    // 日
    int strDay = [[self _substringWithString:carid begin:12 end:2] intValue];
    
    NSTimeZone *localZone = [NSTimeZone localTimeZone];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
    [dateFormatter setTimeZone:localZone];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *date=[dateFormatter dateFromString:[NSString stringWithFormat:@"%d-%d-%d 12:01:01",
                                                strYear, strMonth, strDay]];
    if (date == nil) {
        return NO;
    }
    
    const char *PaperId  = [carid UTF8String];
    // 检验长度
    if(18 != strlen(PaperId)) return NO;
    // 校验数字
    for (int i = 0; i < 18; i++) {
        if ( !isdigit(PaperId[i]) && !(('X' == PaperId[i] || 'x' == PaperId[i]) && 17 == i) ) {
            return NO;
        }
    }
    
    // 验证最末的校验码
    for (int i=0; i<=16; i++) {
        lSumQT += (PaperId[i]-48) * R[i];
    }
    
    if (sChecker[lSumQT%11] != PaperId[17] ) {
        return NO;
    }
    return YES;
}

+ (BOOL)yc_isValidBankCardNumber:(NSString *)bankCardNumber {

    NSString * const BANKCARD = @"^(\\d{16}|\\d{19})$";
    
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",BANKCARD];
    return [predicate evaluateWithObject:bankCardNumber];


}

- (NSString *)yc_filteredHtml {
    return [NSString yc_filterHTML:self];
}

+ (NSString *)yc_filterHTML:(NSString *)html {
    if (html == nil) {
        return nil;
    }
    NSScanner *scanner = [NSScanner scannerWithString:html];
    NSString *text = nil;
    
    while ([scanner isAtEnd] == NO) {
        // 找到标签的起始位置
        [scanner scanUpToString:@"<" intoString:nil];
        // 找到标签的结束位置
        [scanner scanUpToString:@">" intoString:&text];
        // 替换字符
        html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>",text]
                                               withString:@""];
    }
    
    return html;
}

- (NSString *)yc_addPrefix:(NSString *)prefix {
    if (prefix == nil || prefix.length == 0) {
        return self;
    }
    
    return [NSString stringWithFormat:@"%@%@", prefix, self];
}

- (NSString *)yc_addSubfix:(NSString *)subfix {
    if (subfix == nil || subfix.length == 0) {
        return self;
    }
    
    return [NSString stringWithFormat:@"%@%@", self, subfix];
}

+ (NSString *)yc_documentPath {
    return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
}

+ (NSString *)yc_tmpPath {
    return [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];
}

+ (NSString *)yc_cachePath {
    return [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
}

+ (NSString *)yc_pathWithFileName:(NSString *)fileName {
    return [self yc_pathWithFileName:fileName ofType:nil];
}

+ (NSString *)yc_pathWithFileName:(NSString *)fileName ofType:(NSString *)type {
    return [[NSBundle mainBundle] pathForResource:fileName ofType:type];
}

- (NSURL *)yc_toURL {
    return [NSURL URLWithString:[self stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}

+ (NSString *)yc_base64StringFromData:(NSData *)data length:(NSUInteger)length {
    unsigned long ixtext, lentext;
    long ctremaining;
    unsigned char input[3], output[4];
    short i, charsonline = 0, ctcopy;
    const unsigned char *raw;
    NSMutableString *result;
    
    lentext = [data length];
    if (lentext < 1) {
        return @"";
    }
    result = [NSMutableString stringWithCapacity: lentext];
    raw = [data bytes];
    ixtext = 0;
    
    while (true) {
        ctremaining = lentext - ixtext;
        if (ctremaining <= 0) {
            break;
        }
        for (i = 0; i < 3; i++) {
            unsigned long ix = ixtext + i;
            if (ix < lentext) {
                input[i] = raw[ix];
            }
            else {
                input[i] = 0;
            }
        }
        output[0] = (input[0] & 0xFC) >> 2;
        output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
        output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
        output[3] = input[2] & 0x3F;
        ctcopy = 4;
        switch (ctremaining) {
            case 1:
                ctcopy = 2;
                break;
            case 2:
                ctcopy = 3;
                break;
        }
        
        for (i = 0; i < ctcopy; i++) {
            [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
        }
        
        for (i = ctcopy; i < 4; i++) {
            [result appendString: @"="];
        }
        
        ixtext += 3;
        charsonline += 4;
        
        if ((length > 0) && (charsonline >= length)) {
            charsonline = 0;
        }
    }
    return result;
}



- (NSString *)yc_URLEncode {
    NSString *result =
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)self,
                                                              NULL,
                                                              CFSTR("!*'();:@&;=+$,/?%#[] "),
                                                              kCFStringEncodingUTF8));
    return [result yc_trim];
}

//+ (NSString *)yc_AESEncrypt:(NSString *)text password:(NSString *)password {
//  NSData *encryptedData = [[text yc_toData] yc_AES256EncryptedUsingKey:[password yc_SHA256] error:nil];
//  NSString *base64EncodedString  = [NSString yc_base64StringFromData:encryptedData
//                                                           length:[encryptedData length]];
//
//  return base64EncodedString;
//}
//
//+ (NSString *)yc_AESDecrypt:(NSString *)base64EncodedString password:(NSString *)password {
//  NSData *encryptedData = [NSData yc_base64DataFromString:base64EncodedString];
//  NSData *decryptedData = [encryptedData yc_AES256DecryptedUsingKey:[password yc_SHA256]
//                                                           error:nil];
//
//  return [decryptedData yc_toString];
//}

#pragma mark - Private
+ (NSString *)_substringWithString:(NSString *)str begin:(NSInteger)begin end:(NSInteger )end {
    return [str substringWithRange:NSMakeRange(begin, end)];
}

/**
 * 功能:判断是否在地区码内
 * 参数:地区码
 */
+ (BOOL)_areaCode:(NSString *)code {
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    [dic setObject:@"北京" forKey:@"11"];
    [dic setObject:@"天津" forKey:@"12"];
    [dic setObject:@"河北" forKey:@"13"];
    [dic setObject:@"山西" forKey:@"14"];
    [dic setObject:@"内蒙古" forKey:@"15"];
    [dic setObject:@"辽宁" forKey:@"21"];
    [dic setObject:@"吉林" forKey:@"22"];
    [dic setObject:@"黑龙江" forKey:@"23"];
    [dic setObject:@"上海" forKey:@"31"];
    [dic setObject:@"江苏" forKey:@"32"];
    [dic setObject:@"浙江" forKey:@"33"];
    [dic setObject:@"安徽" forKey:@"34"];
    [dic setObject:@"福建" forKey:@"35"];
    [dic setObject:@"江西" forKey:@"36"];
    [dic setObject:@"山东" forKey:@"37"];
    [dic setObject:@"河南" forKey:@"41"];
    [dic setObject:@"湖北" forKey:@"42"];
    [dic setObject:@"湖南" forKey:@"43"];
    [dic setObject:@"广东" forKey:@"44"];
    [dic setObject:@"广西" forKey:@"45"];
    [dic setObject:@"海南" forKey:@"46"];
    [dic setObject:@"重庆" forKey:@"50"];
    [dic setObject:@"四川" forKey:@"51"];
    [dic setObject:@"贵州" forKey:@"52"];
    [dic setObject:@"云南" forKey:@"53"];
    [dic setObject:@"西藏" forKey:@"54"];
    [dic setObject:@"陕西" forKey:@"61"];
    [dic setObject:@"甘肃" forKey:@"62"];
    [dic setObject:@"青海" forKey:@"63"];
    [dic setObject:@"宁夏" forKey:@"64"];
    [dic setObject:@"新疆" forKey:@"65"];
    [dic setObject:@"台湾" forKey:@"71"];
    [dic setObject:@"香港" forKey:@"81"];
    [dic setObject:@"澳门" forKey:@"82"];
    [dic setObject:@"国外" forKey:@"91"];
    
    if ([dic objectForKey:code] == nil) {
        return NO;
    }
    return YES;
}

+ (NSData *)_dataWithBase64EncodedString:(NSString *)string {
    
    if (string == nil)
        [NSException raise:NSInvalidArgumentException format:@""];
    if ([string length] == 0)
        return [NSData data];
    
    static char *decodingTable = NULL;
    if (decodingTable == NULL) {
        decodingTable = malloc(256);
        if (decodingTable == NULL)
            return nil;
        memset(decodingTable, CHAR_MAX, 256);
        NSUInteger i;
        
        const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        for (i = 0; i < 64; i++)
            decodingTable[(short)encodingTable[i]] = i;
    }
    
    const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
    if (characters == NULL)     //  Not an ASCII string!
        return nil;
    char *bytes = malloc((([string length] + 3) / 4) * 3);
    if (bytes == NULL)
        return nil;
    NSUInteger length = 0;
    
    NSUInteger i = 0;
    while (YES) {
        char buffer[4];
        short bufferLength;
        for (bufferLength = 0; bufferLength < 4; i++) {
            if (characters[i] == '\0')
                break;
            if (isspace(characters[i]) || characters[i] == '=')
                continue;
            buffer[bufferLength] = decodingTable[(short)characters[i]];
            if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!
            {
                free(bytes);
                return nil;
            }
        }
        
        if (bufferLength == 0)
            break;
        if (bufferLength == 1)      //  At least two characters are needed to produce one byte!
        {
            free(bytes);
            return nil;
        }
        
        //  Decode the characters in the buffer to bytes.
        bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
        if (bufferLength > 2)
            bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
        if (bufferLength > 3)
            bytes[length++] = (buffer[2] << 6) | buffer[3];
    }
    
    bytes = realloc(bytes, length);
    return [NSData dataWithBytesNoCopy:bytes length:length];
}
-(BOOL)yc_isContainString:(NSString *)str {
    NSRange range = [self rangeOfString:str];
    return range.location != NSNotFound;
}



#pragma mark - 获取设备当前网络IP地址
+ (NSString *)getIPAddress:(BOOL)preferIPv4
{
    NSArray *searchArray = preferIPv4 ?
    @[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    
    NSDictionary *addresses = [self getIPAddresses];
    // LJXLog(@"addresses: %@", addresses);
    
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
     {
         address = addresses[key];
         //筛选出IP地址格式
         if([self isValidatIP:address]) *stop = YES;
     } ];
    return address ? address : @"0.0.0.0";
}

+ (BOOL)isValidatIP:(NSString *)ipAddress {
    if (ipAddress.length == 0) {
        return NO;
    }
    NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
    
    NSError *error;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error];
    
    if (regex != nil) {
        NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])];
        
        if (firstMatch) {
            //            NSRange resultRange = [firstMatch rangeAtIndex:0];
            //            NSString *result=[ipAddress substringWithRange:resultRange];
            //输出结果
            //LJXLog(@"%@",result);
            return YES;
        }
    }
    return NO;
}

+ (NSDictionary *)getIPAddresses
{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

+ (NSString *)lr_stringDate {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"YYYY-MM-dd hh:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
    return dateString;
}



//身份证号

+ (BOOL) yc_validateIdentityCard: (NSString *)identityCard
{
    
    if (identityCard.length != 18)
    {
        return NO;
    }
    
    NSMutableArray *IDArray = [NSMutableArray array];
    
    // 遍历身份证字符串,存入数组中
    
    for (int i = 0; i < 18; i++) {
        
        NSRange range = NSMakeRange(i, 1);
        
        NSString *subString = [identityCard substringWithRange:range];
        
        [IDArray addObject:subString];
        
    }
    
    // 系数数组
    
    NSArray *coefficientArray = [NSArray arrayWithObjects:@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2", nil];
    
    // 余数数组
    
    NSArray *remainderArray = [NSArray arrayWithObjects:@"1", @"0", @"X", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2", nil];
    
    // 每一位身份证号码和对应系数相乘之后相加所得的和
    
    int sum = 0;
    
    for (int i = 0; i < 17; i++) {
        
        int coefficient = [coefficientArray[i] intValue];
        
        int ID = [IDArray[i] intValue];
        
        sum += coefficient * ID;
        
    }
    
    // 这个和除以11的余数对应的数
    
    NSString *str = remainderArray[(sum % 11)];
    
    // 身份证号码最后一位
    
    NSString *string = [identityCard substringFromIndex:17];
    
    // 如果这个数字和身份证最后一位相同,则符合国家标准,返回YES
    
    if ([str isEqualToString:string]) {
        
        return YES;
        
    } else {
        
        return NO;
        
    }
    
}



+ (NSString *)yc_validateIdentifierCardSex:(NSString *)identifierCard
{
    int sexInt = [[identifierCard substringWithRange:NSMakeRange(16, 1)] intValue];
    
    if (sexInt %2 != 0)
    {
        return @"男";
    }
    else
    {
        return @"女";
    }
    
    
}

/*
 传入身份证号算年龄
 */
+ (NSString *)yc_validateIdentifierCardAge:(NSString *)identifierCard
{
    
    NSString * dateStr = [self yc_birthdayStrFromIdentityCard:identifierCard];
    
    
    return [self getAgeWithDateStr:dateStr];
    
    
}

+ (NSString *)getAgeWithDateStr:(NSString *)dateStr
{
    
    NSCalendar *calendar = [NSCalendar currentCalendar];//定义一个NSCalendar对象
    
    NSDate *nowDate = [NSDate date];
    
    NSString *birth = dateStr;
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    //生日
    NSDate *birthDay = [dateFormatter dateFromString:birth];
    
    //用来得到详细的时差
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *date = [calendar components:unitFlags fromDate:birthDay toDate:nowDate options:0];
    
    NSString * ageStr = nil;
    if([date year] >0){
        NSLog(@"%@",[NSString stringWithFormat:(@"%ld岁%ld月%ld天"),(long)[date year],(long)[date month],(long)[date day]]) ;
        ageStr = [NSString stringWithFormat:(@"%ld岁"),(long)[date year]];
    }else if([date month] >0){
        NSLog(@"%@",[NSString stringWithFormat:(@"%ld月%ld天"),(long)[date month],(long)[date day]]);
        ageStr = @"0";
    }else if([date day]>0){
        NSLog(@"%@",[NSString stringWithFormat:(@"%ld天"),(long)[date day]]);
        ageStr = @"0";
    }else {
        NSLog(@"0天");
        ageStr = @"0";
    }
    
    return ageStr;
    
    
    
}



+ (NSString *)yc_validateIdentifierCardWithDate:(NSString *)date
{
    return [self getAgeWithDateStr:date];
    
    
}


+(NSString *)yc_birthdayStrFromIdentityCard:(NSString *)numberStr
{
    NSMutableString *result = [NSMutableString stringWithCapacity:0];
    NSString *year = nil;
    NSString *month = nil;
    
    BOOL isAllNumber = YES;
    
    NSString *day = nil;
    if([numberStr length]<14)
        return result;
    
    //**截取前12位
    NSString *fontNumer = [numberStr substringWithRange:NSMakeRange(0, 11)];
    
    //**检测前12位否全都是数字;
    const char *str = [fontNumer UTF8String];
    const char *p = str;
    while (*p!='\0') {
        if(!(*p>='0'&&*p<='9'))
            isAllNumber = NO;
        p++;
    }
    if(!isAllNumber)
        return result;
    
    
    year = [NSString stringWithFormat:@"%@",[numberStr substringWithRange:NSMakeRange(6, 4)]];
    month = [numberStr substringWithRange:NSMakeRange(10, 2)];
    day = [numberStr substringWithRange:NSMakeRange(12,2)];
    
    
    [result appendString:year];
    [result appendString:@"-"];
    [result appendString:month];
    [result appendString:@"-"];
    [result appendString:day];
    return result;
    
}



//不能输入数字
+ (BOOL)yc_inputShouldNumber:(NSString *)inputString {
    
    BOOL res = NO;
    
    if (inputString.length == 0) return NO;
    
    
    NSArray * shuziarr = @[@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9"];
    
    
    int i = 0 ;
    while (i< shuziarr.count) {
        
        
        if ([inputString containsString:shuziarr[i]]) {
            
            res = YES;
            break;
        }
        
        i++;
    }
    return res;
}




@end





